/* bug7fix.c

   10 threads contribute 1000000 to a global count variable.  Without
   mutex locks the final count is considerably short.  This fixes the
   bug in bug7.c
*/
#include <pthread.h>
#include <stdio.h>
#include <sys/time.h>

#define NTHREADS 10

/* The PTHREAD_MUTEX_INITIALIZER macro initializes the static mutex, 
   setting its attributes to default values. This macro should only be used 
   for static mutexes, as no error checking is performed. */
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;

int counter = 0;  

void *thread_function(void *dummyPtr) {
   long i;
   printf("Thread number %x\n", pthread_self());
   pthread_mutex_lock( &mutex1 );                /*** added ***/
   for (i=0 ; i < 1000000 ; i++) counter++;
   pthread_mutex_unlock( &mutex1 );              /*** added ***/
   return NULL;
}

int main() {
   struct timeval tv1, tv2;
   struct timezone tz;
   pthread_t thread_id[NTHREADS];
   int i, j;

   gettimeofday(&tv1, &tz);

   for (i=0; i < NTHREADS; i++)
      pthread_create( &thread_id[i], NULL, thread_function, NULL );

   for (j=0; j < NTHREADS; j++)
      pthread_join( thread_id[j], NULL);

   gettimeofday(&tv2, &tz);

   /* Now that all threads are complete, print the final result which  */
   /* is correct and print the time it took                            */
   printf("Total time: %f sec\n", (tv2.tv_usec-tv1.tv_usec)/1000000.0);
   printf("Final counter value: %d\n", counter);
}

